/**
 * &emit 自定义事件参数名
 * 父组件使用如下：
 * <angle_selector @on-degree-change="onDegreeChange"></angle_selector>
 */
const CALLBACK_NAME = 'onDegreeChange'
/**
 * currentDegrees 取值精度
 */
const PRECISION = 2
/**
 * 常量
 */
const TEN = 10
/**
 * 记录 showScope、choseScope等数组存放最小范围值的索引
 */
const MIN = 0
/**
 * 记录 showScope、choseScope等数组存放最大范围值的索引
 */
const MAX = 1
/**
 * 画布可用宽度
 */
var width
/**
 * 画布可用高度
 */
var height
/**
 * 当前角度（中心线指向的刻度）
 */
var currentDegrees
/**
 * 步长（刻度线之间的间距）
 */
var stepX
/**
 * 触摸记录点X坐标
 */
var downX
/**
 * 零刻度线X坐标
 */
var zeroX
/**
 * 可允许的零刻度线最大X坐标
 */
var maxZeroX
/**
 * 可允许的零刻度线最小X坐标
 */
var minZeroX
/**
 * 中心刻度线X坐标
 */
var centerLineX
export default {
    data: {
    /**
     *  用于在画布上绘制的 CanvasRenderingContext2D 实例
     */
        ctx: null
    },
    props: {
    /**
     *  控件高度
     */
        height: {
            default: 60
        },
    /**
     *  背景颜色
     */
        bgColor: {
            default: 'black'
        },
    /**
     *  可选择范围内角度画笔颜色
     */
        lineColorHigh: {
            default: 'white'
        },
    /**
     *  非可选择范围内角度画笔颜色
     */
        lineColorDark: {
            default: '#b8b6b6'
        },
    /**
     *  可见范围内显示的刻度线条数
     */
        lineDegreeNum: {
            default: 43
        },
    /**
     *  角度条显示范围
     */
        showScope: {
            default: [-90, 90]
        },
    /**
     *  角度条可选择范围
     */
        choseScope: {
            default: [-45, 45]
        },
    /**
     *  中心线Y轴绘制范围
     */
        centerLineY: {
            default: [0.4, 0.9]
        },
    /**
     *  个位刻度线Y轴绘制范围
     */
        singleDegreeLineY: {
            default: [0.6, 0.8]
        },
    /**
     *  十位刻度线Y轴绘制范围
     */
        tenDegreeLineY: {
            default: [0.5, 0.8]
        },
    /**
     *  十位刻度线文字Y轴绘制位置
     */
        textY: {
            default: 0.3
        },
    /**
     *  绘制线条画笔宽度
     */
        lineWidth: {
            default: 2
        },
    /**
     *  绘制字体大小，格式
     */
        font: {
            default: '14px sans-serif'
        },
    /**
     *  绘制字体排列
     */
        textAlign: {
            default: 'center'
        },
    },
    onLayoutReady() {
        this.initParams()
        this.draw()
    },
    touchStart(e) {
        downX = e.touches[0].globalX
        this.draw()
    },
    touchMove(e) {
        this.updateDegree(e.touches[0].globalX - downX)
        downX = e.touches[0].globalX
        this.draw()
    },
    initParams() {
        const canvas = this.$refs.canvas
        this.ctx = canvas.getContext('2d')
        var rect = canvas.getBoundingClientRect()
        height = rect.height
        width = rect.width
        stepX = width / parseFloat(this.lineDegreeNum)
        zeroX = width >> 1
        centerLineX = zeroX
        maxZeroX = zeroX + this.choseScope[MAX] * stepX
        minZeroX = zeroX + this.choseScope[MIN] * stepX
    },
    draw() {
        this.reset()
        this.drawCenterLine()
        this.drawAllDegreeLine()
    },
/**
 * 重置相关设置
 */
    reset() {
        var ctx = this.ctx
        ctx.fillStyle = this.bgColor
        ctx.fillRect(0, 0, width, height)
        ctx.font = this.font
        ctx.textAlign = this.textAlign
        ctx.strokeStyle = this.lineColorHigh
        ctx.lineWidth = this.lineWidth
        this.ctx = ctx
    },
/**
 * 绘制中间刻度线
 */
    drawCenterLine() {
        var ctx = this.ctx
        var path = ctx.createPath2D()
        path.moveTo(centerLineX, height * this.centerLineY[MIN])
        path.lineTo(centerLineX, height * this.centerLineY[MAX])
        ctx.stroke(path)
        this.ctx = ctx
    },
/**
 * 绘制所有刻度线
 */
    drawAllDegreeLine() {
        for (var i = this.showScope[MIN];i <= this.showScope[MAX]; i++) {
            this.drawDegree(i)
        }
    },
/**
 * 绘制刻度线
 * degree ：当前绘制的刻度线
 */
    drawDegree(degree) {
        var drawX = zeroX + degree * stepX
        // 超出可视范围的刻度线不作绘制
        if (drawX < 0 || drawX > width) {
            return
        }
        var ctx = this.ctx
        if (degree < this.choseScope[MIN] || degree > this.choseScope[MAX]) {
            ctx.fillStyle = this.lineColorDark
            ctx.strokeStyle = this.lineColorDark
        } else {
            ctx.fillStyle = this.lineColorHigh
            ctx.strokeStyle = this.lineColorHigh
        }
        var path = ctx.createPath2D()
        if (degree % TEN == 0) {
            ctx.fillText(degree.toString(), drawX, height * parseFloat(this.textY))
            path.moveTo(drawX, height * this.tenDegreeLineY[MIN])
            path.lineTo(drawX, height * this.tenDegreeLineY[MAX])
        } else {
            path.moveTo(drawX, height * this.singleDegreeLineY[MIN])
            path.lineTo(drawX, height * this.singleDegreeLineY[MAX])
        }
        ctx.stroke(path)
        this.ctx = ctx
    },
/**
 * 计算并返回当前选择角度
 * moveX：当前touchMove事件与上次事件的X坐标值变化量
 */
    updateDegree(moveX) {
        var degrees = (zeroX + moveX - (width >> 1)) / stepX
        if (degrees > this.choseScope[MAX]) {
            currentDegrees = this.choseScope[MAX]
            zeroX = maxZeroX
        } else if (degrees < this.choseScope[MIN]) {
            currentDegrees = this.choseScope[MIN]
            zeroX = minZeroX
        } else {
            currentDegrees = -degrees
            zeroX += moveX
        }
        this.$emit(CALLBACK_NAME, {
            degree: currentDegrees.toFixed(PRECISION)
        })
    }
}
